package com.tzu.ft.transfer.server;

import com.tzu.ft.base.FTConfig;
import com.tzu.ft.base.FTConst;
import com.tzu.ft.base.ResultParam;
import com.tzu.ft.base.SendParam;
import com.tzu.ft.base.TransferTools;
import com.tzu.ft.transfer.ServerTaskFactory;
import com.tzu.ft.transfer.ServerTaskRunning;
import com.tzu.ft.transfer.ServerUI;
import com.tzu.ft.ui.FTUI;
import com.tzu.ft.ui.comps.ProcessPanel;
import com.tzu.ft.ui.comps.ReceiveDialog;
import com.tzu.ft.ui.utils.FTUITools;
import com.tzu.utils.StringTools;
import com.tzu.ssl.KeyInfo;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.file.Paths;

/**
 * 服务端
 */
public abstract class Server {

    public static final int BUFFER_SIZE = 512 * 1024;

    protected ServerSocket serverSocket;
    protected int port;

    /**
     * 初始化
     */
    public abstract void init(int port, KeyInfo keyinfo) throws Exception;

    /**
     * 接收文件发送
     */
    public void start() throws Exception {
        // 连接写回状态
//        OutputStream outputStream = socket.getOutputStream();
//        IOUtils.write("OK", outputStream, "UTF-8");
//        outputStream.flush();
//        System.out.println("写入状态OK");
        while (true) {
            // 等待接收
            final Socket asocket = serverSocket.accept();
            TransferTools.settingServer(asocket);
            // 显示信息
            showinfo(asocket);
            // 创建运行时对象
            ServerTaskRunning running = new ServerTaskRunning() {
                private ServerTaskRunning running;

                @Override
                public void run() {
                    running = this;
//					socket = asocket;
                    ftuiMain = ServerTaskFactory.uimain;
                    serverUI = new ServerUI() {
                        @Override
                        public String getSavePath(String filename, String filesize) {
                            String path = ReceiveDialog.showConfirmInfo(ftuiMain.mainFrame, filename, filesize);
                            return path;
                        }

                        @Override
                        public void startFail(String msg) {
                            FTUITools.showDialogError(ftuiMain.mainFrame, "错误", msg);
                        }

                        @Override
                        public void processStatus(String filetype, String filesize, String usdtime, double precent,
                                                  String speed) {
                        	if (null != processPanel) {
                        		 processPanel.showRun();
                                 processPanel.showFiletypeAndSize(filetype, filesize);
                                 processPanel.showSpeedAndInfo(speed, true);
                                 processPanel.showPrecent(precent);
                                 processPanel.showUsetime(usdtime);
							}
                        }

                        @Override
                        public void finish(int exit, String msg) {
                            processPanel.delete();
                        }
                    };

                    // 处理文件
                    try (DataInputStream dataInputStream = TransferTools.getDataInputStream(socket.getInputStream());
                         DataOutputStream dataOutputStream = TransferTools
                                 .getDataOutputStream(socket.getOutputStream());) {

                        // 接收信息
                        SendParam param = TransferTools.readInfo(dataInputStream, SendParam.class);
                        // 获取文件信息
                        String savepath = null;
                        String defpath = FTConfig.getDefaultSavePath();
                        // 默认存储路径存在
                        //提取中间路径。判断是否存在
                        String middlePath = StringTools.isBlank(param.getDirPath()) ? "" : param.getDirPath();
                        if (StringTools.isNotBlank(defpath)) {
                            // 创建中间路径
                            File middlefile = Paths.get(defpath, middlePath).toFile();
                            if (!middlefile.exists() || !middlefile.isDirectory()) {
                                middlefile.mkdirs();
                            }
                            savepath = Paths.get(defpath, middlePath, param.getFileName()).toString();
                        } else {
                            // 提示存储，用户选择路径
                            savepath = serverUI.getSavePath(param.getFileName(),
                                    TransferTools.takeFileSize(param.getFileLength(), 3));
                            if (StringTools.isBlank(savepath)) {
                                serverUI.finish(1, "用户取消了传输");
                                // 销毁处理
                                ServerTaskFactory.destory(running);
                            }
                        }

                        File file = new File(savepath);
                        title = file.getName();

                        // ui处理
                        String tippath = middlePath + File.separator + file.getName();
                        // 添加进度及处理
                        processPanel = new ProcessPanel(FTUI.down_panel_index++, title, tippath, ftuiMain.panelDownlist);
                        processPanel.showFiletypeAndSize(TransferTools.getFileExt(param.getFileName()),
                                TransferTools.takeFileSize(param.getFileLength(), 3));
                        ftuiMain.panelDownlist.add(processPanel, 0);// 添加到最前面
                        ftuiMain.flushScoll();
                        // 设置进度条上的按钮执行事件
                        processPanel.setProcessAction(new ProcessPanel.ProcessAction() {

                            @Override
                            public void stop() {
                                // TODO Auto-generated method stub
                            }

                            @Override
                            public void exit() {
                                ServerTaskFactory.destory(running);
                            }
                        });

                        // 断点续传
                        if (file.exists()) {
                            // 返回状态
                            TransferTools.sendInfo(dataOutputStream,
                                    new ResultParam(FTConst.FT_STATUS_CODE_101, file.length()).toJSON());
                        } else {
                            // 返回状态
                            TransferTools.sendInfo(dataOutputStream,
                                    new ResultParam(FTConst.FT_STATUS_CODE_100).toJSON());
                        }

                        // 接收文件
                        System.out.println("开始接收文件：" + file.getName());
                        TransferTools.receiveFile(dataInputStream, file, param.getFileLength(), file.length(),
                                serverUI);
                        System.out.println("接收完成");
                        // 关闭
//                        socket.close();
                        ServerTaskFactory.destory(running);
                        serverUI.finish(1, "传输完成");
                    } catch (IOException e) {
                        e.printStackTrace();
                        processPanel.showSpeedAndInfo("接收失败：" + e.getMessage(), false);
                    }

                }
            };
            // 提前设定run
            running.setSocket(asocket);
            // 执行任务
            ServerTaskFactory.addTask(running);

        }
    }

    public void exit() throws Exception {
        serverSocket.close();
    }

    protected void showinfo(Socket socket) {
        InetAddress inetAddress = socket.getInetAddress();
        String address = inetAddress.getHostAddress();
        int serverport = socket.getPort();
        System.out.println(
                "===================接收：" + address + ":" + serverport + "=======================================");
    }
}
